home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 February: Tool Chest / Apple Developer CD Series Tool Chest February 1996 (Apple Computer)(1996).iso / Sample Code / AOCE Sample Code / PowerTalk Access Modules / Sample SMSAM / SampleSMSAM Source / BuildingBlocks / Buffer.cp next >
Encoding:
Text File  |  1995-07-28  |  11.0 KB  |  459 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        Buffer.cp
  3.  
  4.     Copyright:    © 1991-1994 by Apple Computer, Inc.
  5.                 All rights reserved.
  6.  
  7.     Part of the AOCE Sample SMSAM Package.  Consult the license
  8.     which came with this software for your specific legal rights.
  9.  
  10. */
  11.  
  12.  
  13.  
  14. #ifndef __BUFFER__
  15. #include "Buffer.h"
  16. #endif
  17.  
  18. #ifndef    __DEBUGASSERT__
  19. #include "DebugAssert.h"
  20. #endif
  21.  
  22. #ifndef    __DEBUGCONSTANTS__
  23. #include "DebugConstants.h"
  24. #endif
  25.  
  26. #pragma segment Buffer
  27.  
  28. class TDebugFlag;
  29. extern TDebugFlag chrisFlag;
  30.  
  31. /***********************************|****************************************/
  32.  
  33. ABuffer::ABuffer ()
  34. {
  35. }
  36.  
  37. /***********************************|****************************************/
  38.  
  39. ABuffer::~ABuffer ()
  40. {
  41. }
  42.  
  43. /***********************************|****************************************/
  44.  
  45. short
  46. CompareBuffers ( const void* aa, unsigned long alen, const void* bb, unsigned long blen )
  47. {
  48.     register short diff = 0;
  49.     unsigned long c = alen < blen ? alen : blen;
  50.     const char* a = (char*) aa;
  51.     const char* b = (char*) bb;
  52.  
  53.     while ( c-- > 0 )
  54.     {
  55.         diff = *a++ - *b++;
  56.  
  57.         if ( diff != 0 )
  58.             break;
  59.     }
  60.  
  61.     if ( diff == 0 )
  62.         diff = (short) ( (long) alen - (long) blen );
  63.  
  64.     return diff;
  65. }
  66.  
  67. /***********************************|****************************************/
  68.  
  69. ABuffer&
  70. ABuffer::operator = ( const ABuffer& that )
  71. {
  72.     if ( this != &that )
  73.     {
  74.         ReadFrom ( that.GetPhysicalStart (), that.GetPhysicalLength () );
  75.     }
  76.     else
  77.     {
  78.         ASSERT ( this != &that );
  79.     }
  80.  
  81.     return *this;
  82. }
  83.  
  84. /***********************************|****************************************/
  85.  
  86. unsigned long
  87. ABuffer::ReadFrom ( const void* source, unsigned long sourceLength )
  88. {
  89.     unsigned long newLength = SetPhysicalLength ( sourceLength );
  90.     ASSERT ( newLength >= sourceLength );
  91.     unsigned long copiedLength = Minimum ( newLength, sourceLength );
  92.     BlockMove ( source, (void*) GetPhysicalStart (), copiedLength );
  93.     return copiedLength;
  94. }
  95.  
  96. /***********************************|****************************************/
  97.  
  98. unsigned long
  99. ABuffer::WriteTo ( void* dest, unsigned long destLength ) const
  100. {
  101.     unsigned long desiredLength = GetPhysicalLength ();
  102.     ASSERT ( destLength >= desiredLength );
  103.     unsigned long copiedLength = Minimum ( destLength, desiredLength );
  104.     BlockMove ( GetPhysicalStart (), dest, copiedLength );
  105.     return copiedLength;
  106. }
  107.  
  108. /***********************************|****************************************/
  109.  
  110. Boolean
  111. ABuffer::operator == ( const ABuffer& that ) const
  112. {
  113.     return 0 == ::CompareBuffers ( GetPhysicalStart (), GetPhysicalLength (), that.GetPhysicalStart (), that.GetPhysicalLength () );
  114. }
  115.  
  116. /***********************************|****************************************/
  117.  
  118. void
  119. ABuffer::FillBuffer ( unsigned char c )
  120. {
  121.     unsigned char* p = (unsigned char*) GetPhysicalStart ();
  122.     unsigned long length = GetPhysicalLength ();
  123.  
  124.     while ( length-- > 0 )
  125.         *p++ = c;
  126. }
  127.  
  128. /***********************************|****************************************/
  129.  
  130. #ifndef    __FSTREAM__
  131. #include "FStream.h"
  132. #endif
  133.  
  134. extern ostream& DumpHex (ostream& s, const void *p, unsigned long size);
  135.  
  136. ostream&
  137. ABuffer::operator >> ( ostream& stream ) const
  138. {
  139.     if ( chrisFlag.Flag ( kExtensiveBufferDescribe ) )
  140.     {
  141.         stream << "ABuffer @ " << (void*) this << "\n";
  142.         stream << "\tGetPhysicalLength (): " << GetPhysicalLength () << "\n";
  143.         stream << "\tGetPhysicalStart (): ";
  144.         DumpHex ( stream, (char*) GetPhysicalStart (), GetPhysicalLength () );
  145.     }
  146.     else
  147.     {
  148.         stream << GetPhysicalLength () << " bytes @ " << (void*) GetPhysicalStart () << '\n';
  149.     }
  150.  
  151.     return stream;
  152. }
  153.  
  154. /***********************************|****************************************/
  155. /***********************************|****************************************/
  156.  
  157. CBuffer::CBuffer ():
  158.     ABuffer (),
  159.     fIsExternal ( false )
  160. {
  161.     SetPhysicalLength ( sizeof ( unsigned long ) );
  162. }
  163.  
  164. /***********************************|****************************************/
  165.  
  166. CBuffer::CBuffer ( unsigned long length ):
  167.     ABuffer (),
  168.     fIsExternal ( false )
  169. {
  170.     SetPhysicalLength ( length );
  171. }
  172.  
  173. /***********************************|****************************************/
  174.  
  175. CBuffer::CBuffer ( const void* source, unsigned long sourceLength ):
  176.     ABuffer (),
  177.     fIsExternal ( false )
  178. {
  179.     SetPhysicalLength ( sourceLength );
  180.     BlockMove ( (Ptr) source,  (Ptr) GetPhysicalStart (),  (Size) GetPhysicalLength () );  //removed const 
  181. }
  182.  
  183. /***********************************|****************************************/
  184.  
  185. CBuffer::CBuffer ( const ABuffer& that ):
  186.     ABuffer (),
  187.     fIsExternal ( false )
  188. {
  189.     SetPhysicalLength ( that.GetPhysicalLength () );
  190.     BlockMove ( (Ptr) that.GetPhysicalStart (), (Ptr) GetPhysicalStart (), (Size) GetPhysicalLength () );
  191. }
  192.  
  193. /***********************************|****************************************/
  194.  
  195. CBuffer::CBuffer ( const CBuffer& that ):
  196.     ABuffer (),
  197.     fIsExternal ( false )
  198. {
  199.     SetPhysicalLength ( that.GetPhysicalLength () );
  200.     BlockMove ( (Ptr) that.GetPhysicalStart (), (Ptr) GetPhysicalStart (), (Size)  GetPhysicalLength () );
  201. }
  202.  
  203. /***********************************|****************************************/
  204.  
  205. CBuffer&
  206. CBuffer::operator = ( const CBuffer& that )
  207. {
  208.     if ( this != &that )
  209.     {
  210.         ReadFrom ( that.GetPhysicalStart (), that.GetPhysicalLength () );
  211.     }
  212.     else
  213.     {
  214.         ASSERT ( this != &that );
  215.     }
  216.  
  217.     return *this;
  218. }
  219.  
  220. /***********************************|****************************************/
  221.  
  222. CBuffer::~CBuffer ()
  223. {
  224.     if ( fIsExternal )
  225.         DeallocatePtr( (Ptr) fType.fExternal.fBuffer );
  226. }
  227.  
  228. /***********************************|****************************************/
  229.  
  230. unsigned long
  231. CBuffer::SetPhysicalLength ( unsigned long length )
  232. {
  233.     if ( fIsExternal )
  234.         DeallocatePtr( (Ptr) fType.fExternal.fBuffer );
  235.  
  236.     if ( length > kBufferMaxInternalLength )
  237.     {
  238.         fType.fExternal.fBuffer = FAILNewPtr( length );
  239.         if ( fType.fExternal.fBuffer )
  240.         {
  241.             #if debug
  242.             memset ( fType.fExternal.fBuffer, '\0', (unsigned int) length );
  243.             #endif
  244.             fIsExternal = true;
  245.             return fType.fExternal.fLength = length;
  246.         }
  247.         else
  248.         {
  249.             ASSERT(noErr == MemError ());
  250.             fIsExternal = false;
  251.             return fType.fInternal.fLength = kBufferMaxInternalLength;
  252.         }
  253.     }
  254.     else
  255.     {
  256.         fIsExternal = false;
  257.         return fType.fInternal.fLength = (unsigned char) length;
  258.     }
  259. }
  260.  
  261. /***********************************|****************************************/
  262.  
  263. ostream&
  264. CBuffer::operator >> ( ostream& s ) const
  265. {
  266.     ABuffer::operator >> ( s );
  267.  
  268. #if debug
  269.     if ( chrisFlag.Flag ( kExtensiveBufferDescribe ) )
  270.     {
  271.         s << "\tfIsExternal: " << (short) fIsExternal << '\n';
  272.  
  273.         if ( fIsExternal )
  274.         {
  275.             s << "\tfLength: " << fType.fExternal.fLength << '\n';
  276.             s << "\tfBuffer: " << fType.fExternal.fBuffer;
  277.         }
  278.         else
  279.         {
  280.             s << "\tfLength: " << (short) fType.fInternal.fLength;
  281. //             s << "\tfBuffer: " << fType.fInternal.fBuffer;
  282.         }
  283.     }
  284. #endif
  285.  
  286.     return s;
  287. }
  288.  
  289. /***********************************|****************************************/
  290. /***********************************|****************************************/
  291.  
  292. CPrefixBuffer::CPrefixBuffer ( Prefix prefix, unsigned long logicalLength ):
  293.     ABuffer (),
  294.     fBuffer ( logicalLength + prefix ),
  295.     fSource ( nil ),
  296.     fPrefix ( prefix ),
  297.     fUpdate ( false )
  298. {
  299.     UpdatePrefixWithLength ( 0 );
  300. }
  301.  
  302. /***********************************|****************************************/
  303.  
  304. CPrefixBuffer::CPrefixBuffer ( const ABuffer& source, Prefix prefix ):
  305.     ABuffer (),
  306.     fBuffer ( (const char*) source.GetPhysicalStart () - prefix, source.GetPhysicalLength () + prefix ),
  307.     fSource ( (ABuffer*) &source ),
  308.     fPrefix ( prefix ),
  309.     fUpdate ( false )
  310. {
  311.     UpdatePrefixWithLength ( source.GetPhysicalLength () );
  312. }
  313.  
  314. /***********************************|****************************************/
  315.  
  316. CPrefixBuffer::CPrefixBuffer ( ABuffer& source, Boolean update, Prefix prefix ):
  317.     ABuffer (),
  318.     fBuffer ( (const char*) source.GetPhysicalStart () - prefix, source.GetPhysicalLength () + prefix ),
  319.     fSource ( &source ),
  320.     fPrefix ( prefix ),
  321.     fUpdate ( update )
  322. {
  323.     UpdatePrefixWithLength ( source.GetPhysicalLength () );
  324. }
  325.  
  326. /***********************************|****************************************/
  327.  
  328. CPrefixBuffer::CPrefixBuffer ( const void* source, unsigned long length, Prefix prefix ):
  329.     ABuffer (),
  330.     fBuffer ( (char*) source - prefix, length + prefix ),
  331.     fSource ( nil ),
  332.     fPrefix ( prefix ),
  333.     fUpdate ( false )
  334. {
  335.     UpdatePrefixWithLength ( length );
  336. }
  337.  
  338. /***********************************|****************************************/
  339.  
  340. void
  341. CPrefixBuffer::UpdatePrefixWithLength ( unsigned long length )
  342. {
  343.     void* start = (void*) fBuffer.GetPhysicalStart ();
  344.  
  345.     switch ( fPrefix )
  346.     {
  347.         case kByte:
  348.             *(unsigned char*) start = (unsigned char) length;
  349.         break;
  350.  
  351.         case kWord:
  352.             *(unsigned short*) start = (unsigned short) length;
  353.         break;
  354.  
  355.         case kLong:
  356.             *(unsigned long*) start = (unsigned long) length;
  357.         break;
  358.     }
  359. }
  360.  
  361. /***********************************|****************************************/
  362.  
  363. unsigned long
  364. CPrefixBuffer::SetLogicalLength ( unsigned long requestedLogicalLength )
  365. {
  366.     unsigned long requestedPhysicalLength = requestedLogicalLength + fPrefix;
  367.     unsigned long actualPhysicalLength = fBuffer.GetPhysicalLength ();
  368.  
  369.     if ( actualPhysicalLength < requestedPhysicalLength )
  370.     {
  371.         actualPhysicalLength = fBuffer.SetPhysicalLength ( requestedPhysicalLength );
  372.         ASSERT_RETURN_ZERO ( actualPhysicalLength >= requestedPhysicalLength );
  373.     }
  374.  
  375.     unsigned long actualLogicalLength = actualPhysicalLength - fPrefix;
  376.     UpdatePrefixWithLength ( actualLogicalLength );
  377.     return actualLogicalLength;
  378. }
  379.  
  380. /***********************************|****************************************/
  381.  
  382. unsigned long
  383. CPrefixBuffer::GetLogicalLength () const
  384. {
  385.     switch ( fPrefix )
  386.     {
  387.         case kByte: return *(unsigned char*) fBuffer.GetPhysicalStart ();
  388.         case kWord: return *(unsigned short*) fBuffer.GetPhysicalStart ();
  389.         case kLong: return *(unsigned long*) fBuffer.GetPhysicalStart ();
  390.     };
  391.     return 0;    //keep compiler happy
  392. }
  393.  
  394. /***********************************|****************************************/
  395.  
  396. CPrefixBuffer::~CPrefixBuffer ()
  397. {
  398.     UpdateNow ();
  399. }
  400.  
  401. /***********************************|****************************************/
  402.  
  403. unsigned long
  404. CPrefixBuffer::UpdateNow ()
  405. {
  406.     if ( fUpdate && fSource )
  407.         return fSource->ReadFrom ( GetLogicalStart (), GetLogicalLength () );
  408.     else
  409.         return 0;
  410. }
  411.  
  412. /***********************************|****************************************/
  413.  
  414. ostream&
  415. CPrefixBuffer::operator >> ( ostream& s ) const
  416. {
  417.     ABuffer::operator >> ( s );
  418.  
  419. #if debug
  420.     if ( chrisFlag.Flag ( kExtensiveBufferDescribe ) )
  421.     {
  422. //         s << "\tfBuffer: " << fBuffer << '\n';
  423.         s << "\tfSource: " << fSource << '\n';
  424.         s << "\tfPrefix: " << (short) fPrefix << '\n';
  425.         s << "\tfUpdate: " << (short) fUpdate;
  426.     }
  427. #endif
  428.  
  429.     return s;
  430. }
  431.  
  432. /***********************************|****************************************/
  433. /***********************************|****************************************/
  434.  
  435. CWrapperBuffer::CWrapperBuffer ( void* source, unsigned long length ):
  436.     ABuffer (),
  437.     fSource ( source ),
  438.     fLength ( length )
  439. {
  440. }
  441.  
  442. /***********************************|****************************************/
  443.  
  444. CWrapperBuffer::~CWrapperBuffer ()
  445. {
  446. }
  447.  
  448. /***********************************|****************************************/
  449.  
  450. unsigned long
  451. CWrapperBuffer::SetPhysicalLength ( unsigned long newLength )
  452. {
  453.     ASSERT ( newLength == fLength);
  454.  
  455.     return fLength;
  456. }
  457.  
  458. /***********************************|****************************************/
  459.